home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
basic
/
qbser15.zip
/
QBSERIAL.DOC
< prev
next >
Wrap
Text File
|
1990-03-23
|
22KB
|
505 lines
Serial I/O Routines for use with QuickBASIC
This library will provide you with serial I/O communications
routines for use in QuickBASIC 4.x (with or without PDQ), and the
Microsoft Basic Compiler 7.x Professional Development System. No
longer will you be forced to use the poor communications support
provided by QB. This program will allow you to control
communications ports 1 - 4 at speeds of up to 115200 baud. You will
no longer have problems with the DTR signal. It is left in the same
state it was in when before this driver is called, or it can be
controlled by your program. The serial driver includes XON/XOFF and
CTS handshaking. Serial input is interrupt driven, with incoming
XOFF flow control (if enabled) to prevent overrunning the input
buffer. These are the same serial I/O routines used in the User
Database System Doors "Query Door" and "Upload Door".
The driver was written using Microsoft's QuickC version 2.01. This
driver can ONLY be used with QuickBASIC version 4.x and BC7.0 PDS.
The reason is that versions of QuickBASIC prior to 4.0 do not
support the extensive multi-language interface that QB4.x has (via
the DECLARE statement). It seems to work fine with BASCOM 6 also,
although I did have problems with BC6 when the entire QuickC
library (MLIBCE) was used for linking. Since only portions of the C
library are included here, the error seems to be eliminated.
Throughout this manual QBSERIAL or QB will be used to refer to both
QuickBASIC and the new Basic Compiler 7.0 PDS.
Before the driver can be used, the following DECLARE statements
must be added to the beginning of your QB program:
DECLARE SUB OpenComm CDECL ALIAS "_open_comm" (BYVAL Port%, BYVAL_
Wlen%, BYVAL Parity%, BYVAL Baud&, BYVAL HS%)
DECLARE SUB CloseComm CDECL ALIAS "_close_comm" ()
DECLARE FUNCTION WriteChar% CDECL (BYVAL Ascii%)
DECLARE FUNCTION ReadChar% CDECL ()
DECLARE SUB Transmit CDECL ALIAS "_transmit_string" (addr$)
DECLARE FUNCTION DataWaiting% CDECL ALIAS "_data_waiting" ()
DECLARE SUB ClearInputBuffer CDECL ALIAS "_clear_input_buffer" ()
DECLARE SUB CarrierDetect CDECL ALIAS "_carrier_detect_flag"_
(BYVAL OnOff%)
DECLARE SUB CDtrap CDECL ALIAS "_trap_mode" (BYVAL OnOff%)
DECLARE FUNCTION CarrierLost% CDECL ALIAS "_carrier_state" ()
DECLARE SUB DTRcontrol CDECL ALIAS "_dtr" (BYVAL OnOff%)
These declarations specify all the entry points into the serial
driver, They are in the include file QBSERIAL.DEC. DO NOT change
them or the driver may not function.
Refer to the included sample programs SIMPLE.BAS & PCBDOOR.BAS,
they use most of the calls described below.
QBSERIAL User Manual - V 1.5 Page 1
Port Initialization
OpenComm Port%, Wordlen%, Parity%, Baudrate&, HS%
Port% an integer value of 0, 1, 2, 3, or 4. If the specified
port is 1 to 4, the driver seizes the serial interrupt
for this port (IRQ3 or 4). You must restore this
interrupt vector before program termination (explained
later). If the port is specified as ZERO the driver
enters "LOCAL" mode. This allows you to call the driver
with data, but the driver wont actually send anything.
This is useful when working with "doors".
Wordlen% an integer specifying the word length of the serial data.
It has a value of 7 or 8.
Parity% an integer, 0 = NONE, 1 = ODD, 2 = EVEN.
BaudRate& is a LONG INTEGER representing the desired baud rate.
Valid numbers are 0, 300, 1200, 2400, 4800, 9600, 19200,
38400, 57600, and 115200. The value you send is NOT
checked and I assume you could generate crazy baud rates
if desired. 115200 is the absolute maximum rate that can
be generated. If you specify a baud rate of ZERO then the
serial port is used AS-IS. The rate, word length, &
parity are NOT changed. This is useful for door operation
since the port is already initialized at the proper
settings when you get control.
HS% an integer specifying the type of handshake you wish to
use between the CPU and Modem (or destination device).
Valid numbers are: 0 = NO handshake, 1 = XON/XOFF, 2 =
CTS, 3 = XON/XOFF and CTS.
Serial Output
To send a string of data out the serial port, you use the
"Transmit" call as follows:
Temp$ = "Transmit this..."
Transmit Temp$
or
Transmit "Send this also...."
If you want to transmit single characters, you can use the
"WriteChar" function. Transmit calls WriteChar to send the actual
QBSERIAL User Manual - V 1.5 Page 2
characters to the port. If you wish to use WriteChar, it has the
following format:
Status% = WriteChar(Char%)
Char% is the integer value of the character you want to send, it is
not a string. Status% is an integer returned by WriteChar, it is
NON-ZERO if the character was actually sent to the port, and ZERO
if the character WAS NOT SENT because of No Carrier. Please note
that WriteChar will loop indefinitely on CTS hold, XOFF hold, or
Transmit Buffer Busy. These loops will exit if carrier is lost
(unless carrier detection is disabled), and return a ZERO status%.
WriteChar gives you more low level control of the sending of
characters, but you must send each character separately and monitor
its status.
The Transmit function monitors the status of its calls to WriteChar
and triggers QuickBASIC's User Event trap (UEVENT) if a failure
occurs. The UEVENT trap is used by default. You can disable the use
of this event trap in the event you already use the UEVENT trap for
something else. Therefore, by default, carrier loss detection in
your program is done with the ON UEVENT GOSUB/UEVENT ON statements.
The example programs show the use of this method. By default UEVENT
is also used for catching carrier loss on keyboard input. this is
described below.
Serial Input
Serial input is managed with three functions: DataWaiting,
ReadChar, & ClearInputBuffer. DataWaiting is used to test the input
buffer to see if any characters need to be read from it. ReadChar
is then called to get the characters. ClearInputBuffer flushes the
input buffer of any existing characters. Both example programs
contain a subroutine called "KeyboardInput" that demonstrates the
use of these calls. It also properly handles input from the local
and remote keyboards, and can be the routine you use in your
programs if you wish. Basically the procedure for reading the
remote keyboard (serial input) is as follows:
IF DataWaiting THEN
C$ = CHR$(ReadChar)
END IF
The DataWaiting function also monitors the state of the carrier
detect signal and triggers, by default, the user event trap
(UEVENT) if carrier is lost. As you can see a singular trap routine
catches carrier loss on output as well as input. You will notice
that the "KeyboardInput" subroutine loops using DataWaiting, and as
such, carrier is constantly checked while waiting for input. If the
QBSERIAL User Manual - V 1.5 Page 3
ReadChar function is called when no data is available (as indicated
by DataWaiting) a NULL character is returned.
If XOFF/XON or BOTH is enabled, then the serial buffer will be
protected from overfills. When the buffer reaches 75% of capacity,
an XOFF will be sent on the serial output. When the buffer empties
out to 25% of capacity, an XON will be sent. The capacity of the
input buffer is 1024 bytes.
Carrier Detect Control
Implemented in version 1.1 is a function call to allow the calling
program to control if the driver senses carrier. The driver
defaults to carrier detection ON unless you implicitly turn it off.
The following call has been added to do this:
CarrierDetect 0 [or] 1
Specifying a ZERO turns carrier detection OFF. Even if you have the
UEVENT turned ON, no trap will occur if carrier is lost. Also, any
internal loops (such as XOFF wait) will NOT exit if carrier is
lost. Specifying a ONE turns carrier detection back ON.
Examples for the use of this would be where "plain Jane" serial I/O
is required where no modem handshake signals are used (simple 3
wire EIA). Carrier detection must be disabled in this mode
otherwise no data is sent. Another use might be in a program that
dials out on a modem to initiate a connection. Obviously at the
start of the call there is no carrier, and detection must be turned
off in order to send data to the modem. After a connection is
established, then the carrier detect can turned on again by the
program. Most applications however will not even use this function
call, since carrier detection defaults to ON.
Carrier Loss Detection
As mentioned above, by default, the UEVENT trap is used to detect
when a loss of carrier occurs (assuming carrier detection is
enabled as explained above). Implemented in version 1.2 are two new
function calls that allow you to detect loss of carrier without
using the UEVENT trap. While I feel that using UEVENT is the
simplest way to catch a carrier loss in a program, it is possible
that UEVENT might need to be used by something else. The two
functions used for this purpose are:
CDtrap 0 [or] 1
and
QBSERIAL User Manual - V 1.5 Page 4
X% = CarrierLost
CDtrap needs to be used ONLY when UEVENT is used for another
purpose. Setting CDtrap to ZERO instructs the driver not to trip
the UEVENT flag in Basic if carrier is lost. As you can see if your
program uses UEVENT for some other purpose, you wouldn't want the
driver causing false interrupts (CDtrap 1 returns driver to
normal). If you do not plan to use UEVENT for carrier loss
detection, or for ANYTHING else, then you DO NOT have to set CDtrap
to zero. As long as you do not turn UEVENT ON in your program,
Basic will not respond to the UEVENT flag even if it was tripped.
The other function call allows to you to 'poll' for the state of
carrier. the "CarrierLost" functions returns a value indicating if
carrier is present of not. CarrierLost returns a NON-ZERO value
when there is NO carrier, and a ZERO when there IS carrier.
CarrierLost is a real time function, it returns the current carrier
condition at the time of the call. This allows you to code simple
IF or DO loops to detect loss:
IF CarrierLost THEN
..process carrier loss
END IF
Do NOT confuse these two functions with the "CarrierDetect"
function described in the previous section. That function controls
whether CD is checked before sending data, and what to do if no CD
is present. CDtrap only controls whether UEVENT is to be tripped or
not, and CarrierLost only returns the current carrier state.
Program Termination
Since "OpenComm" seizes interrupt vectors, these vectors need to be
restored BEFORE your program ends. If you neglect to restore these
vectors, you are guaranteed a crash. The routine used to reset the
vectors is: CloseComm. Only use CloseComm if you specified a port
value of 1, 2, 3, or 4 on the OpenComm call. If you specified a
port value of ZERO (Local mode) the interrupt vectors are NOT
grabbed, and do not need to be reset. CloseComm also resets any
UART registers to their original value, it also resets the
programmable interrupt controller (8259 PIC) to its original
settings.
Data Terminal Ready (DTR)
Everybody that has used QuickBASIC's OPEN COMn statement is very
familiar with the problems of the DTR signal. Apparently Microsoft
QBSERIAL User Manual - V 1.5 Page 5
felt that DTR would never be needed after a program terminates.
Anybody who has ever tried to write a door, or chain from one
program to another has cursed this decision at some time during
their programs development. This driver handles the DTR with a
different view. When you close the comm channel the DTR signal is
left in the same state it was when you opened the comm channel. For
door applications, this is a must.
Implemented at version 1.2 is a function call that allows your
program to control the DTR signal:
DTRcontrol 1 [or] 0 ' 0 = DTR OFF, 1 = DTR ON
Additionally when you use DTRcontrol to change the state of the DTR
signal it also instructs the driver to leave it this way when the
CloseComm function is called. Remember that the driver leaves DTR
the way it found it when OpenComm was called. If you used some
other method to change DTR after OpenComm was called, it would
automatically return to that original state when you called
CloseComm. Therefor only DTRcontrol should be used if you wish to
change the state of DTR.
Cresent's PDQ Library
An object module for use with PDQ is also included. This version is
intended to be used ONLY with QuickBASIC 4.x. Actually the PDQ
version is identical to the QB version. The only difference is that
the PDQ version has no calls to UEvent (since there is no UEvent
routine in PDQ). You could in fact use either version (QBSER.OBJ or
QBSERPQD.OBJ) with QB 4.x if you never wanted to use UEvent as your
carrier detect trap. If you select to use QBSERPDQ.OBJ, substitute
it for QBSER.OBJ in the following paragraphs.
Linking
Since object modules are provided for both QB and BC7, you will
need to select which one to use for your program. The additional
library (SERIAL.LIB) only contains routines from the C library that
are required by the driver. The file QBSER.OBJ should be used for
programs compiled with QuickBASIC, and BC7SER.OBJ is to be used for
programs compiled with BC7 PDS. Typical link command lines would
look like this:
Link yourprog qbser,,,serial;
or
Link yourprog bc7ser,,,serial;
QBSERIAL User Manual - V 1.5 Page 6
An alternate way would be to add to the SERIAL.LIB the obj file you
will always use. This requires you to have the LIB program (which
comes with both versions of basic). To all the object file to the
lib, use the following command:
Lib serial +qbser;
or
Lib serial +bc7ser;
after doing this, you can link as follows:
Link yourprog,,,serial;
Remember that the library you modify can only be used with the
version of Basic whose object module you add.
Quick Libraries
If you wish to develop programs from within the environment, you
will first need to create a Quick library using one of the object
modules (QBSER.OBJ or BC7SER.OBJ) and the SERIAL.LIB file. To
create a Quick lib for QuickBASIC 4.x, use the following Link
command:
Link QBSER SERIAL.LIB,,,BQLB4x/q
Where "BQLB4x" is one of the following: BQLB40.LIB, BQLB41.LIB, or
BQLB45.LIB. Use the one that came with your compiler. If you use
the wrong BQLB file you might get an "Invalid Format" error when
attempting to start QuickBASIC. QBSER.OBJ & SERIAL.LIB may also be
added to Quick Libraries containing other routines and OBJ's as
well.
To create a Quick Library for use within QBX (BC7's environment)
use the following link command (be sure to use Link v5.05 that came
with BC7):
Link BC7SER SERIAL.LIB,,,QBXQLB/q;
Remember too, that you can also add BC7SER.OBJ & SERIAL.LIB to
Quicklibs containing other routines.
QBSERIAL User Manual - V 1.5 Page 7
Specifications
The following port addresses and interrupts are used:
Comm Base Address IRQ
1 3F8 hex 4
2 2F8 hex 3
3 3E8 hex 4
4 2E8 hex 3
Support
I'm reachable in the Interlink Basic conference, or the number
below. I'll help there if you have questions. No other support is
necessary. Bugs will be tended to if required, and good suggestions
tend to be implemented.
In the spirit of programmer to programmer I am not requesting any
compensation for the use of these routines other than you
acknowledge in your documentation that you are using them. If you
feel they are worth something and you want to send me something I
won't refuse it! If you are using them in a PCBoard door, a copy of
the door for our system would be a nice gesture!
However, if you plan to use QBserial in a commercial product for
resale, please contact me first.
Source Code
The source code for QBserial is now available. The source is ONLY
available by signing a license agreement. The source may be used
for internal use only. The source may not be distributed by you to
any other person, even if you make changes to it. Nor can the
resulting object code be sold or distributed. Modifications can
only be used in your end product, and without any type of royalty.
The license fee for the QBserial source code is $75.00. Please
contact me if you are interested.
Jeff Sumberg
Sysop(2) - SailBoard BBS
Wayne, NJ, 201-831-8152
[ or ]
Box 212
Ringwood, NJ, 07456
QBSERIAL User Manual - V 1.5 Page 8
Changes and Revisions
06/09/89 1.0 Initial Release
06/21/89 1.1 Added carrier detection control. Calling
program can turn detection off and on as
desired. Necessary if data sending/receiving
required if carrier isn't present.
09/01/89 1.2 Fixed a bug in Readchar where 'extended'
characters (ASCII 128 to 255) were causing an
Illegal Function Call in the CHR$() conversion
(because they were being returned as negative
numbers). Extended character may now be
received properly. Added three new functions:
CDtrap, CarrierLost, and DTRcontrol.
1.3
1.4 Un-released interim versions.
03/24/90 1.5 Added support for Basic Compiler 7.0 PDS and
PDQ. Added sections to manual about Linking,
Source code availability, and updated section
on Quicklibs. Separate object files now
supplied for QB, BC7, and PDQ.
QBSERIAL User Manual - V 1.5 Page 9